package com.atguigu.lease.web.app.service.impl;


import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.atguigu.lease.common.exceptions.LeaseException;
import com.atguigu.lease.common.jwts.JwtUtil;
import com.atguigu.lease.common.redis.RedisConstant;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.UserInfo;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.app.service.LoginService;
import com.atguigu.lease.web.app.service.UserInfoService;
import com.atguigu.lease.web.app.vo.user.LoginVo;
import com.atguigu.lease.web.app.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private Client client;
    @Autowired
    private UserInfoService userInfoService;

    /**
     * 生成验证码
     * 发往手机，存储redis,key:app:login:phone，code
     * 注意：
     * 判定是否重复发送验证码，
     * redis没有对应验证码,发送验证码
     * 存储验证码到reds,key:app:login:phone
     * @param phone
     */
    @Override
    public void getCode(String phone) throws Exception {
        String key=RedisConstant.APP_LOGIN_PREFIX + phone;
        //判定是否重复发送验证码
        Boolean hasKey = redisTemplate.hasKey(key);
        if(hasKey){
            //重复发送验证码
            throw new LeaseException(ResultCodeEnum.APP_SEND_SMS_TOO_OFTEN);
        }
        //2.不存在，生成6为验证码
        Random random = new Random();
        int code = 100000 + random.nextInt(900000);
        //发送验证码到手机上
        SendSmsRequest smsRequest = new SendSmsRequest();
        smsRequest.setPhoneNumbers(phone);
        smsRequest.setSignName("阿里云短信测试"); //签名
        smsRequest.setTemplateCode("SMS_154950909"); //模板编号 阿里云的短信测试的模板编号
        smsRequest.setTemplateParam("{\"code\":\"" + code + "\"}\n"); //替代模板中的code
        client.sendSms(smsRequest);
        //存储验证码到redis上
        redisTemplate.opsForValue().set(key,code,RedisConstant.APP_LOGIN_CODE_TTL_SEC, TimeUnit.SECONDS);
    }

    /**
     * 根据手机号和验证码登录,生成token并返回
     * 获取验证码
     * 判断验证码是否过期
     * 验证码是否错误
     * phone判断是否存在用户，不存在创建
     * 存在，判断是否被禁用
     * 没有被禁用，根据id,手机号生成token并返回
     * @param loginVo
     * @return
     */

    @Override
    public String login(LoginVo loginVo) {
        String key=RedisConstant.APP_LOGIN_PREFIX + loginVo.getPhone();
        //获取验证码
        Integer redisCode = (Integer) redisTemplate.opsForValue().get(key);
        //判断验证码是否过期
        if(ObjectUtils.isEmpty(redisCode)){
            //过期
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_EXPIRED);
        }
        //验证码是否错误
        if(!redisCode.equals(Integer.parseInt(loginVo.getCode()))){
            System.out.println("redisCode = " + redisCode);
            System.out.println("loginVo = " + loginVo);
            //错误
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
        }
        //根据phone判断是否存在用户，不存在创建
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper=new LambdaQueryWrapper<>();
        userInfoLambdaQueryWrapper.eq(UserInfo::getPhone,loginVo.getPhone());
        UserInfo userInfo = userInfoService.getOne(userInfoLambdaQueryWrapper);
        if(ObjectUtils.isEmpty(userInfo)){
            userInfo=new UserInfo();
            userInfo.setPhone(loginVo.getPhone());
            userInfo.setStatus(BaseStatus.ENABLE);
            userInfo.setNickname("佚名"+loginVo.getPhone().substring(5));
            userInfoService.save(userInfo);
        }
        //判断用户是否被禁用
        if(userInfo.getStatus().equals(BaseStatus.DISABLE)){
            throw new LeaseException(ResultCodeEnum.APP_ACCOUNT_DISABLED_ERROR);
        }
        //没有被禁用，根据id,手机号生成token并返回
        String accessToken = JwtUtil.createToken(userInfo.getId(), loginVo.getPhone());
        return accessToken;
    }


}
